package com.kim.authorization.server.config.extend;

import com.kim.authorization.server.config.util.AuthProperties;
import com.kim.oauth.common.constants.Oauth2ExceptionEnum;
import com.kim.oauth.common.model.UserAccount;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * 用户名密码 + 验证码方式鉴权
 */
@Component
@Slf4j
public class VerificationCodeAuthenticator extends UsernamePasswordAuthenticator {

    /**
     * 用户名密码+ 验证码授权类型
     */
    private final static String AUTH_TYPE = "verification";

    /**
     * redis
     */
    private final RedisTemplate<String, Object> redisTemplate;

    public VerificationCodeAuthenticator(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 根据用户名密码+ 验证码方式进行认证
     *
     * @param entity 集成认证实体
     * @return org.surge.oauth2common.model.UserAccount
     */
    @Override
    public UserAccount authenticate(IntegrationAuthenticationEntity entity) {
        // 获取验证码
        String verificationCode = entity.getAuthParameter(AuthProperties.VERIFICATION_CODE_COMMON);
        if (StringUtils.isEmpty(verificationCode)) {
            throw new OAuth2Exception(Oauth2ExceptionEnum.VERIFICATION_CODE_EMPTY.getMsg());
        }
        // 获取唯一key
        String key = entity.getAuthParameter(AuthProperties.VERIFICATION_CODE_KEY_PARAMETER_NAME);
        if (StringUtils.isEmpty(key)) {
            throw new OAuth2Exception(Oauth2ExceptionEnum.VERIFICATION_CODE_UNICODE_KEY_EMPTY.getMsg());
        }
        log.info("客户端输入验证码 -> {}", verificationCode);
        // redis中获取验证码
        String redisVerificationCode = Objects.requireNonNull(redisTemplate.opsForHash().get(AuthProperties.VERIFICATION_CODE_COMMON, key),"验证码key不存在或已过期").toString();
        log.info("redis获取验证码 -> {}", redisVerificationCode);
        // 是否输入正确
        if (!redisVerificationCode.equalsIgnoreCase(verificationCode)) {
            throw new OAuth2Exception(Oauth2ExceptionEnum.VERIFICATION_CODE_ERR.getMsg());
        }
        // 删除验证码
        redisTemplate.opsForHash().delete(AuthProperties.VERIFICATION_CODE_COMMON, key);
        return super.authenticate(entity);
    }

    /**
     * 认证类型为空时为用户名密码+ 验证码方式
     * {@inheritDoc}
     */
    @Override
    public boolean support(IntegrationAuthenticationEntity entity) {
        return AUTH_TYPE.equals(entity.getAuthType());
    }
}
